/**
 *
 */
package com.alibaba.wallstreet.uitls;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import com.ali.b2b.crm.base.i18n.AppI18N;
import com.ali.b2b.crm.base.resource.Option;
import com.ali.b2b.crm.base.resource.OptionDo;
import com.ali.b2b.crm.base.resource.ResourceManager;
import com.alibaba.citrus.util.i18n.LocaleUtil;
import com.alibaba.wallstreet.base.ResourceOptionDo;
import com.alibaba.wallstreet.dal.mapper.WsResourceMapperExt;
import com.alibaba.wallstreet.dal.model.WsResource;
import com.alibaba.wallstreet.dal.model.WsResourceExample;

/**
 * @author wenbo.mawb
 * @author nathan.yuhm
 */
public class ResourceManagerUtil {

    public enum ResourceName {
        /** 通用资源配置项 */
        COMMON_RESOURCES,

        /** 农业银行币种 :从标准币种CNY转到农行接口币种 */
        ABC_CURRENCY_TYPE,
        /** 农业银行币种：从农行接口币种转到标准币种CNY */
        ABC_CURRENCY_TYPE_SWAP,
        /** 农业银行省份代码 :从标准代码转换成农行代码 */
        ABC_PROVINCE_CODE,

        /** 民生银行币种 :从标准币种CNY转到民生银行接口币种 */
        CMBC_CURRENCY_TYPE,
        /** 民生银行币种：从农行接口币种转到标准币种CNY */
        CMBC_CURRENCY_TYPE_SWAP,

        /** 招商银行币种 :从标准币种CNY转到招行接口币种 */
        CMB_CURRENCY_TYPE,
        /** 招商银行币种：从招行接口币种转到标准币种CNY */
        CMB_CURRENCY_TYPE_SWAP,

        /** 宁波银行币种 :从标准币种CNY转到宁波银行接口币种 */
        NBCB_CURRENCY_TYPE,
        /** 宁波银行币种：从宁波银行接口币种转到标准币种CNY */
        NBCB_CURRENCY_TYPE_SWAP,
        /** 中信银行币种 :从标准币种CNY转到中信银行接口币种 */
        CNCB_CURRENCY_TYPE,
        /** 中信银行币种：从中信银行接口币种转到标准币种CNY */
        CNCB_CURRENCY_TYPE_SWAP,

        /** 工商银行币种 :从标准币种CNY转到工行接口币种 */
        ICBC_CURRENCY_TYPE,
        /** 工商银行币种：从工行接口币种转到标准币种CNY */
        ICBC_CURRENCY_TYPE_SWAP,

        /** 平安银行币种 :从标准币种CNY转到平安银行接口币种 */
        PAB_CURRENCY_TYPE,
        /** 平安银行币种：从平安银行接口币种转到标准币种CNY */
        PAB_CURRENCY_TYPE_SWAP,

        /** 支付宝币种 :从标准币种CNY转到支付宝接口币种 */
        ALIPAY_CURRENCY_TYPE,
        /** 支付宝币种：从支付宝接口币种转到标准币种CNY */
        ALIPAY_CURRENCY_TYPE_SWAP,

        /** 银行币种中文名：从标准币种CNY转到对应的中文名 */
        CURRENCY_TYPE_ALIAS,

        /** 银行币种中文名：从标准币种对应的中文名转到英文 */
        CURRENCY_TYPE_ALIAS_SWAP,

        /** 同步时点默认值 */
        SYNC_CRON_DEFAULT,

        /** 同步频率默认值 */
        SYNC_FREQ_DEFAULT,

        /** 国家类型 */
        COUNTRY,

        /** 国家类型英文名称 */
        COUNTRY_EN,

        /** 根据国家名称获取国家代号 */
        COUNTRY_SWAP,

        /** 省份类型 */
        PROVINCE,

        /** 根据省份名称获取省份代号 */
        PROVINCE_SWAP,

        /** 城市类型 */
        CITY,

        /** 根据城市名称获取城市代号 */
        CITY_SWAP,

        /** 银行类型 */
        BANK,
        /** 通过银行全称取银行编码 */
        BANK_SWAP,

        /** 银行支行类型 */
        BANK_BRANCH,
        /** 通过银行支行全称取银行编码 */
        BANK_BRANCH_SWAP,

        /** 邮件组类型 */
        MAIL_GROUP,

        /** 默认同步时间类型 */
        DEFAULT_SYNC_TIME,

        /** 默认同步频率组 */
        DEFAULT_SYNC_FREQ,

        /** 默认同步时点组 */
        DEFAULT_SYNC_CRON,

        /** 招行登陆名 */
        CMB_LOGIN_NAME,

        /** 中信银行登陆名 */
        CNCB_LOGIN_NAME,

        /** 工作日 */
        HOLIDAYS,
        /** 系统日期距离N天后接近付款到期日 */
        ADJUST_PAY_DAY,
        /** 支付组 */
        GWS_PAYMENT_GROUP,
        /** 代发类型 */
        GWS_PAYROLL_TYPE,
        /** 国际化 */
        i18n,
        /** 系统来源编码 */
        SYSTEM_SOURCE_CODE,
        /** 业务类型 */
        BUSI_TYPE,
        /** 科目结构 */
        COA_INFO,
        /** 税率 */
        TAX_RATE,
        /** 过滤的账薄 */
        EXCLUDING_SET_OF_BOOKINFO,
        /** 公共资源 */
        COMMON_RESOURCE,
        /** 省份code匹配 */
        PROVINCE_CODE_MAPPING,
        /** 城市code匹配 */
        CITY_CODE_MAPPING,
        /** 根据oucode */
        GWS_HSBC_CORP_CODE,
        /** 根据oucode */
        GWS_HSBC_ACH_ID,
        /** 账龄配置 */
        GWS_ACCOUNT_AGING_CONFIG,
        /** 资金预测_日 */
        GWS_NOTICE_DAY_BETWEEN,
        /** 资金预测_月 */
        GWS_NOTICE_MONTH_BETWEEN,
        /** 发票邮寄信息 */
        INVOICE_MAIL_INFO,
        /** BU发票邮寄 */
        BU_INVOICE_MAIL,
        /** OU发票邮寄 */
        OU_INVOICE_MAIL,
        /** 预提财务复审 */
        ACRU_CONFIRMER,
        /** 预提部门段 */
        ACRU_DEPARTMENT,
        /** 发票导出列表 */
        EXCEL_COLUMN_KEY,
        /** 报销还款账号OU */
        TES_REPAY_ACCOUNT_OU,
        /** 地区 */
        AREA,
        /** 洲 */
        CONTINENT,
        /** 包含地区的国家 */
        COUNTRY_2,
        /** 发票类型 */
        INVOICE_TYPE,
        /** 支付渠道 */
        PAY_CHANNELS,
        /** 结算业务类别 */
        FPM_BUSINESS_CATEGORY,
        /** 结算业务审批人类型 */
        FPM_APPROVER_TYPE,
        /** 结算业务财务接口人 */
        FPM_FINANCE_INTERFACE_PERSON,
        /** 结算业务线 */
        FPM_BUSINESS_LINE,
        /** 对公/对私账户类型 */
        ACCOUNT_TYPES,
        /** 各个接入系统的notify topic */
        NOTIFY_TOPICS,
        /** 通知老格式的交易状态的应用 */
        OLD_MSG_APPS,
        /** 银行账户默认支付能力 */
        DEFAULT_ACCOUNT_ABILITY;
    }

    public enum SystemFlag {
        /** 产生对账任务标志 */
        F_GEN_CHECK_TRADE_RECORD,
        /** 实时发送同步失败通知邮件标志 */
        F_SEND_SYNC_FAIL_MAIL
    }

    private static final String    TIMER_MASTER  = "TIMER_MASTER";
    private static final String    SYSTEM_FLAG   = "SYSTEM_FLAG";
    private static final String    SYSTEM_CONFIG = "SYSTEM_CONFIG";
    private static ResourceManager resourceManager;
    @Resource
    protected WsResourceMapperExt  wsResourceMapperExt;

    public void setResourceManager(ResourceManager resourceManager) {
        ResourceManagerUtil.resourceManager = resourceManager;
    }

    /**
     * 获取指定资源名称指定key并且返回类型为OptionDo的value
     * 
     * @param resName 资源名称
     * @param key 键
     */
    public static String lookup(ResourceName resName, String key) {
        if (StringUtils.isNotEmpty(key)) {
            OptionDo op = (OptionDo) resourceManager.getResItem(resName.toString(), key);
            if (op != null) {
                return op.getValue();
            }
        }
        return null;
    }

    public static String lookup(ResourceName resName, String key, String defaultValue) {
        String value = lookup(resName, key);
        return StringUtils.isBlank(value) ? defaultValue : value;
    }

    /**
     * 获取指定资源名称指定key并且返回类型为T的对象
     * 
     * @param cls 返回类型
     * @param resName 资源名称
     * @param key 键
     */
    public static <T> T lookup(Class<T> cls, ResourceName resName, String key) {
        if (resName != null && !StringUtils.isEmpty(key)) {
            @SuppressWarnings("unchecked")
            T object = (T) resourceManager.getResItem(resName.toString(), key);
            return object;
        }
        return null;
    }

    /**
     * 返回资源名为resName的资源列表.
     * 
     * @param resName
     * @return
     */
    public static List<?> lookup(ResourceName resName) {
        List<?> list = null;
        if (resName != null) {
            list = resourceManager.getResList(resName.toString());
        }

        if (list == null) {
            list = Collections.emptyList();
        }
        return list;
    }

    public static boolean invalidValue(ResourceName resName, String key) {
        String str = lookup(resName, key);
        return StringUtils.isEmpty(str);
    }

    public static List<?> getResListByGroup(ResourceName resourceName, String groupName, String groupValue) {
        List<?> list = resourceManager.getResListByGroup(resourceName.toString(), groupName, groupValue);
        if (list == null) {
            list = new ArrayList<Object>();
        }
        return list;
    }

    public static List<Option> getOptionListByGroup(ResourceName resName, String groupName, String groupValue) {
        List<Option> list = resourceManager.getOptionListByGroup(resName.toString(), groupName, groupValue);
        if (list == null) {
            list = new ArrayList<Option>();
        }
        return list;
    }

    /**
     * 根据资源值resName返回Values List
     * 
     * @param resName
     * @return
     */
    @SuppressWarnings("unchecked")
    public static List<String> getResourceValueList(ResourceName resName) {
        List<OptionDo> list = (List<OptionDo>) lookup(resName);
        List<String> ret = new ArrayList<String>();
        for (OptionDo optionDo : list) {
            ret.add(optionDo.getValue());
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public static List<OptionDo> getOptionList(ResourceName resName) {
        return (List<OptionDo>) lookup(resName);
    }

    @SuppressWarnings("unchecked")
    public static List<ResourceOptionDo> getResourceOptionList(ResourceName resName) {
        return (List<ResourceOptionDo>) lookup(resName);
    }

    @SuppressWarnings("unchecked")
    public static List<OptionDo> getTreeNodes(ResourceName resName, ResourceName groupName, String rootKey) {
        return (List<OptionDo>) resourceManager.getTreeNodes(resName.name(), groupName.name(), rootKey);
    }

    public static String getI18nMessage(String key) {
        String i18nString = null;
        if (!StringUtils.isEmpty(key)) {
            AppI18N i18n = lookup(AppI18N.class, ResourceName.i18n, key);
            if (null != i18n) {
                i18nString = i18n.getValue(LocaleUtil.getContext().getLocale().toString());
                if (StringUtils.isBlank(i18nString)) {
                    i18nString = key;
                }
            }
        }
        return i18nString;
    }

    public String getDefaultAppMasterIp() {
        WsResourceExample example = new WsResourceExample();
        // 资源表需要有唯一一个有效的主机
        example.createCriteria().andTypeEqualTo(TIMER_MASTER).andValue1EqualTo("true");
        return getResValue(example);
    }

    public String getAppMasterIp(String appName) {
        String mastIp = null;
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo("TIMER_SWITCH").andNameEqualTo(appName);
        WsResource res = getRes(example);
        if (res != null) {
            mastIp = res.getValue2();
        }
        if (StringUtil.isBlank(mastIp)) {
            mastIp = getDefaultAppMasterIp();
        }
        return mastIp;
    }

    public String getSystemConfig(String cfgName) {
        return getResourceVal(SYSTEM_CONFIG, cfgName);
    }

    public List<WsResource> getResources(String type) {
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo(type);
        return wsResourceMapperExt.selectByExample(example);
    }

    public String getResourceVal(String type, String name) {
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo(type).andNameEqualTo(name);
        return getResValue(example);
    }

    public String getSystemFlag(SystemFlag systemFlag) {
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo(SYSTEM_FLAG).andNameEqualTo(systemFlag.name());
        return getResValue(example);
    }

    private String getResValue(WsResourceExample example) {
        WsResource res = getRes(example);
        if (res != null) {
            return res.getValue();
        } else {
            return "";
        }
    }

    public WsResource getResource(String type, String name) {
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo(type).andNameEqualTo(name);
        return getRes(example);
    }

    private WsResource getRes(WsResourceExample example) {
        List<WsResource> appResourceList = wsResourceMapperExt.selectByExample(example);
        if (appResourceList.size() == 1) {
            return appResourceList.get(0);
        }
        return null;
    }

    public void updateFlag(WsResource res, String flag) {
        WsResource record = new WsResource();
        record.setId(res.getId());
        record.setValue1(flag);
        wsResourceMapperExt.updateByPrimaryKeySelective(record);
    }

    public boolean isResExists(String type, String name, String value) {
        WsResourceExample example = new WsResourceExample();
        example.createCriteria().andTypeEqualTo(type).andNameEqualTo(name).andValueEqualTo(value);
        List<WsResource> appResourceList = wsResourceMapperExt.selectByExample(example);
        return !CollectionUtils.isEmpty(appResourceList);
    }
}
